package com.carful.xigua.modules.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.carful.xigua.modules.common.util.ControllerClassUtils;
import com.carful.xigua.modules.user.entity.Auth;
import com.carful.xigua.modules.user.mapper.AuthMapper;
import com.carful.xigua.modules.user.service.IAuthService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ad
 * @since 2024-07-11
 */
@Service
public class AuthServiceImpl extends ServiceImpl<AuthMapper, Auth> implements IAuthService {

    @Override
    public void init() {
        String basePackage = "com.carful.xigua.modules.*.controller"; // 替换为您要扫描的包名

        // 创建一个ClassPathScanningCandidateComponentProvider实例
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);

        // 您可以添加过滤器以根据特定条件获取类，例如：
        // 仅获取带有某个注解的类
        TypeFilter annotationFilter = new AnnotationTypeFilter(Controller.class);
        scanner.addIncludeFilter(annotationFilter);

        // 仅获取实现某个接口或继承某个类的类
        // TypeFilter assignableFilter = new AssignableTypeFilter(SampleInterface.class);
        // scanner.addIncludeFilter(assignableFilter);

        // 扫描特定包下的类
        Set<BeanDefinition> beanDefinitions = scanner.findCandidateComponents(basePackage);

        List<Auth> auths = new ArrayList<>();
        auths.add(new Auth().setValue("/").setNotes("所有权限"));

        // 遍历扫描到的类
        for (BeanDefinition beanDefinition : beanDefinitions) {
            String className = beanDefinition.getBeanClassName();
            try {
                Class<?> aClass = Class.forName(className);
                String classPath = ControllerClassUtils.getClassUri(aClass);
                RequestMapping annotation = aClass.getAnnotation(RequestMapping.class);
                if (StringUtils.hasText(annotation.name()) && !auths.contains(new Auth().setValue(classPath).setNotes(annotation.name()))) { // 类注解如果有 name属性，加入模块权限
                    auths.add(new Auth().setValue(classPath).setNotes(annotation.name()));
                }

                Method[] methods = aClass.getDeclaredMethods();
                for (Method method : methods) {
                    String methodPath = ControllerClassUtils.getMethodUri(method);
                    if (methodPath == null) continue;
                    String methodDesc = ControllerClassUtils.getMethodDesc(method);
                    auths.add(new Auth().setValue(classPath + methodPath).setNotes(methodDesc));
                }
            } catch (ClassNotFoundException e) {
                log.error(className + " 初始化权限错误  " + e.getMessage());
            }
        }
        List<Auth> selectList = getBaseMapper().selectList(new LambdaQueryWrapper<>());
        Map<String, Auth> hashMap = selectList.stream().collect(Collectors.toMap(Auth::getValue, a -> a));

        auths = auths.stream().filter(a -> {
            if (!hashMap.containsKey(a.getValue())) {
                return true;
            }
            hashMap.get(a.getValue()).setNotes(a.getNotes());
            updateById(a);
            return false;
        }).toList();
        if (auths.size() != 0) {
            saveBatch(auths);
        }
    }
}
